/**************************************
@ filename    : tb_uart_test_env.sv
@ author      : yyrwkk
@ create time : 2025/04/18 15:45:09
@ version     : v1.0.0
**************************************/
`include "uart_test_env.vh"
`include "clk_rst_gen.sv"
module tb_uart_test_env();
// uart_test_env Inputs
logic         i_clk        ;
logic         i_rst_n      ;
logic         rx           ;
logic         cross_valid  ;
logic [7:0]   cross_data   ;
logic         cross_ready  ;

// uart_test_env Outputs
logic         tx           ;

logic [7:0]   uart_tx_data ;
logic         uart_tx_valid;
logic         uart_tx_ready;

logic [7:0]   uart_rx_data ;
logic         uart_rx_valid;
logic         uart_rx_ready;

uart_tx # (
    .CFG_BAUD_DIV    (`UART_BAUD_DIV   ),
    .CFG_TARGET_BITS (`UART_TARGET_BITS),
    .CFG_PARITY_EN   (`UART_PARITY_EN  ),
    .CFG_PARITY_SEL  (`UART_PARITY_SEL ),
    .CFG_STOP_BITS   (`UART_STOP_BITS  )
) uart_tx_inst (
    .clk_i        (i_clk  ),
    .rstn_i       (i_rst_n),

    .tx_o         (tx           ),
    .busy_o       (             ),

    .tx_data_i    (uart_tx_data ),
    .tx_valid_i   (uart_tx_valid),
    .tx_ready_o   (uart_tx_ready)
);

uart_test_env  uart_test_env_inst (
    .i_clk                   ( i_clk        ),
    .i_rst_n                 ( i_rst_n      ),

    .i_rx                    ( tx           ),
    .o_tx                    ( rx           ),

    .i_wr_valid              ( cross_valid  ),
    .i_wr_data               ( cross_data   ),
    .o_wr_ready              ( cross_ready  ),
    
    .o_rd_valid              ( cross_valid  ),
    .o_rd_data               ( cross_data   ),
    .i_rd_ready              ( cross_ready  )
);


uart_rx  #(
    .CFG_BAUD_DIV    (`UART_BAUD_DIV   ),
    .CFG_TARGET_BITS (`UART_TARGET_BITS),
    .CFG_PARITY_EN   (`UART_PARITY_EN  ),
    .CFG_PARITY_SEL  (`UART_PARITY_SEL )
)uart_rx_inst(
    .clk_i        (i_clk         ),
    .rstn_i       (i_rst_n       ),
    
    .rx_i         (rx            ),

    .busy_o       (              ),
    .err_o        (              ),

    .rx_data_o    (uart_rx_data  ),
    .rx_valid_o   (uart_rx_valid ),
    .rx_ready_i   (uart_rx_ready )
);

task automatic display_queue( string name, bit [7:0] que[$] );
    $display("-------------%s begin -------------",name);
    foreach( que[i] ) begin 
        $display("%x",que[i]);
    end
    $display("-------------%s  end  -------------",name);
endtask

real rd_clk_freq  = 100;
`clk_gen( i_clk, 0, rd_clk_freq, 0 , 0.5, 0, 0   )
`rst_gen( i_rst_n, 0,0,$urandom_range(100,300)   )

initial begin 
    uart_tx_data  = 8'b0;
    uart_tx_valid = 1'b0;
    uart_rx_ready = 1'b1; 
end 

bit [7:0] tx_data[$];
bit [7:0] rx_data[$];

initial begin 
    tx_data.push_back(8'h00);
    tx_data.push_back(8'h01);
    tx_data.push_back(8'h02);
    tx_data.push_back(8'h03);
    tx_data.push_back(8'h04);
end

initial begin 
    #10_000_000;
    $display("[==========timeout===========]");
    $finish;
end

initial begin 
    @(posedge i_clk );
    wait( i_rst_n == 1'b1 );
    @(posedge i_clk );
    foreach(tx_data[i]) begin 
        uart_tx_valid <= 1'b1;
        uart_tx_data  <= tx_data[i];
        @(posedge i_clk iff( uart_tx_valid & uart_tx_ready ));
        @(posedge i_clk );
    end
    uart_tx_data  <= 8'b0;
    uart_tx_valid <= 1'b0;
end 

bit match ;
bit flag  ;
initial begin
    match = 1;
    while(1) begin 
        if( uart_rx_valid & uart_rx_ready ) begin 
            rx_data.push_back(uart_rx_data);
            if( rx_data.size() == tx_data.size()) break; 
        end
        @(posedge i_clk );
    end

    display_queue("tx_data queue",tx_data);
    display_queue("rx_data queue",rx_data);
   
    foreach( tx_data[i] ) begin 
        if(tx_data[i]!=rx_data[i] ) match = 0;
        $display("[tx]: %x,\t [rx]: %x",tx_data[i],rx_data[i]);
    end

    if( match ) $display("[==========match==========]");
    else $display("[=========dismatch=========]");

    $finish;
end

endmodule 



